package com.qf.file.utils;

import com.madgag.gif.fmsware.AnimatedGifEncoder;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

/**
 * @author 30909
 * 对视频进行采样处理
 */
public class GifAndJpgUtil {
    /**
     * 定义每个多少帧截取一帧画面
     */
    public static final int DEFAULT_MARGIN = 2;
    /**
     * 定义默认的帧频率
     */
    public static final int DEFAULT_FRAME_RATE = 10;

    /**
     * 定义指定视频，生吃gif 预览，与jpg封面的方法
     *
     * @param filePath   原视频的位置
     * @param startFrame 起始帧的位置
     * @param frameCount 截帧的总帧数
     * @param frameRate  帧频率
     * @param margin     步长
     */
    public static void buildGifAndJpg(String filePath, int startFrame, int frameCount
            , Integer frameRate, Integer margin) {
        try {
            if (frameRate == null) {
                frameRate = DEFAULT_FRAME_RATE;
            }
            if (margin == null) {
                frameRate = DEFAULT_MARGIN;
            }
            // git 存储路径
            //文件路径不变，文件名不变，后缀改为gif
            String gifPath = filePath.substring(0, filePath.lastIndexOf(".")) + ".gif";
            //构建文件输出流
            FileOutputStream targetFile = new FileOutputStream(gifPath);
            //获取视频文件
            //使用 ffmpeg 引擎逐帧读取
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(filePath);

            //创建一个 java2d 画面转换器

            Java2DFrameConverter converter = new Java2DFrameConverter();
            //让 ffmpeg 开始工作
            ff.start();


            //读取视频总帧数
            Integer videoLength = ff.getLengthInFrames();
            System.out.println("videoLength = " + videoLength);


            //万一视频总帧数不够用怎么办？
            if (startFrame > videoLength
                    ||
                    (startFrame + frameCount * margin) > videoLength) {
                //视频总帧数不够用
                startFrame = 1;
                //这个公式没看懂
                frameCount = (videoLength - startFrame - margin) / margin;
                //
            }
            //现在的帧数一定够用
            //设置ffmpeg的加载的位置
            ff.setAudioFrameNumber(startFrame);

            //实例化一个 gif 编码器
            AnimatedGifEncoder en = new AnimatedGifEncoder();


            //给gif 设置一个帧率
            en.setFrameRate(frameRate);

            //设置 gif 无线循环
            en.start(targetFile);

            //设置生成图片的标志位
            boolean poster = false;


            //逐帧
            for (int i = 0; i < frameCount; i++) {
                if (!poster) {
                    //读取一帧转化为图片
                    Frame f = ff.grabFrame();
                    if (f != null) {
                        String jpgPath = filePath.substring(0, filePath.lastIndexOf(".")) + ".jpg";
                        //传入图片信息
                        File jpgFile = new File(jpgPath);
                        //获取图片信息
                        BufferedImage bufferedImage = converter.getBufferedImage(f);

                        //把图片写到文件上
                        ImageIO.write(bufferedImage, "jpg", jpgFile);
                        poster = true;
                    }
                }
                //去除一帧用于合成 gif
                en.addFrame(converter.convert(ff.grabFrame()));
                //设置下一帧的位置
                ff.setFrameNumber(ff.getFrameNumber() + margin);
            }
            en.finish();
            ff.stop();
            ff.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        buildGifAndJpg("C:\\test\\mp4\\321.mp4", 1, 50, 2, 10);
    }
}

